package util.thread.ordertoperform;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Description：
 * @Author：LiDong
 * @Create：2020/12/2
 * @Version：1.0.0
 */
public class ReentrantLockTest {

    private static final Logger logger = LoggerFactory.getLogger(ReentrantLockTest.class);

    /**
     * 创建可重入锁
     */
    private final ReentrantLock reentrantLock = new ReentrantLock();

    private final Condition oneCondition = reentrantLock.newCondition();
    private final Condition twoCondition = reentrantLock.newCondition();
    private final Condition threeCondition = reentrantLock.newCondition();

    private boolean oneFlag = true;
    private boolean twoFlag = true;

    class One extends Thread {
        @Override
        public void run() {
            // 创建锁
            reentrantLock.lock();
            try {
                logger.info("=====》One线程执行完成...");
                oneFlag = false;
                oneCondition.signalAll();
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            } finally {
                // 释放锁
                reentrantLock.unlock();
            }

        }
    }


    class Two extends Thread {
        @Override
        public void run() {
            reentrantLock.lock();
            try {
                while (oneFlag) {
                    logger.info("----->等待线程one执行完成");
                    twoCondition.await();
                }
                twoFlag = false;
                logger.info("=====》Two线程执行完成...");
                //通知其他线程重新获取锁，该他们执行了
                twoCondition.signalAll();
            } catch (Exception e) {
                logger.error(e.getMessage(), e);

            } finally {
                reentrantLock.unlock();
            }
        }
    }

    class Three extends Thread {
        @Override
        public void run() {
            reentrantLock.lock();
            try {
                while (twoFlag) {
                    logger.info("----->等待线程two执行完成");
                    twoCondition.await();
                }
                //通知其他线程重新获取锁，该他们执行了
                threeCondition.signalAll();
                logger.info("======》Three线程执行完成...");
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            } finally {
                reentrantLock.unlock();
            }
        }
    }

    @Test
    public void test1() throws InterruptedException {
        Thread one = new One();
        one.start();

        Thread two = new Two();
        two.start();

        Thread three = new Three();
        three.start();

        Thread.sleep(5000);
        logger.info("=====>三个子线程结束...");
    }

}
